grammar ESharkDSL;

prog:   stat ;

stat:   expr
    ;

expr:   expr op=(AND|OR) expr # exprOpexpr
    |   NOT? PROTOCOL  # protocol
    |   FIELD_NAME op=(EQ|NE|GT|LT|GE|LE) FIELD_VALUE # protocolFieldNameOpValue
    |   FIELD_VALUE op=(EQ|NE|GT|LT|GE|LE) FIELD_NAME # protocolFieldNameOpValue
    |   NOT? '(' expr ')' # parens
;

PROTOCOL: 'tcp'|'udp'|'arp'|'ip'|'dns'|'ssdp'|'igmp'|'tls'|'smb'|
            'http'|'http2'|'stmp'|'icmp'|'nbns'|'dcerpc'|'nbss'|'sip'|'eth'|'frame';    // 协议

EQ:       'eq' | '==';             // Comparing Values: 相等
NE:       'ne' | '!=';             // Comparing Values: 不等
GT:       'gt' | '>';             // Comparing Values: 大于
LT:       'lt' | '<';             // Comparing Values: 小于
GE:       'ge' | '>=';             // Comparing Values: 大于等于
LE:       'le' | '<=';             // Comparing Values: 小于等于
CONTAINS: 'contains';             // Comparing Values: 包含
MATCHES: 'matches' | '~';             // Comparing Values: 正则
BITWISE_AND: 'bitwise_and' | '&';             // Comparing Values: 按位与非零

AND:       'and' | '&&';             // Combining Expressions: 逻辑与
OR:       'or' | '||';               // Combining Expressions: 逻辑或
NOT:       'not' | '!';              // Combining Expressions: 逻辑非


FIELD_NAME_SEG: DOT [a-z_]+ ;
FIELD_NAME: PROTOCOL (FIELD_NAME_SEG)+ ;
FIELD_VALUE: FLOAT|INT|IP|CIDR|MAC|STRING|HEX_NUM; // 协议字段值类型
MAC: (MAC_SEG)+ HEX_STR_SEG;  // 81:60:03
MAC_SEG: HEX_STR_SEG COLON;
CIDR: IP'/'INT;
IP: INT '.' INT '.' INT '.' INT ;
INT : [0-9]+ ;
FLOAT: [0-9]+'.'[0-9]+;
COLON: ':';
DOT: '.';
HEX_STR_SEG: [0-9a-fA-F][0-9a-fA-F]; // HEX String Segment
HEX_FIRST_SEG: '0'?[0-9a-fA-F]; // 十六进制最左边，可能出现省略前导零的情况
HEX_NUM: '0x'HEX_FIRST_SEG (HEX_STR_SEG)*;         // 0x0901
STRING: [0-9a-zA-Z];
NEWLINE: [\r\n] ;                 // return newlines to parser (is end-statement signal)
WS  :   [ \t]+ -> skip ;             // 忽略空白字符
